/*
 * Entity.h
 *
 *  Created on: 24.10.2012
 *      Author: Martin
 *
 *      Mother class entity
 *      represents one entity on the scene
 */

#pragma once

// entity types
//--------------------------------------------------
#define OBJ_ENTITY		0
#define OBJ_TREE 		1
#define OBJ_BUILDING 	2	
#define OBJ_GRASS		3
#define OBJ_VILLAGER	4
#define OBJ_GATHERER	5
#define OBJ_DEER		6
#define OBJ_BLUMBERJACK 7
#define OBJ_HUNTER		8
#define OBJ_BHUNTER		9
#define OBJ_BUILDER		10
#define OBJ_BBUILDER	11
#define OBJ_STATIC		12
#define OBJ_DYNAMIC		13
#define OBJ_VEGETATION	14
#define OBJ_ANIMAL		15
#define OBJ_BBANK		16
#define OBJ_TAXMAN		17
//--------------------------------------------------

// entity status
//--------------------------------------------------
// don't call draw and control
#define	STATUS_SLEEPING				0

// don't call control, change model to dead model
#define	STATUS_DEAD					1

//	virtual entity, don't call control, draw with alpha
#define	STATUS_VIRTUAL				2

//	entity is ready to new command
#define	STATUS_READY				3

//	age++ entity is under construction
#define	STATUS_UNDER_CONSTRUCTION	4

// entity is placed and waiting for builder
#define	STATUS_PLACED				5

// tree is cut down
#define	STATUS_CUT					6

// entity is mooving to do something
#define	STATUS_GOWORK				7

// entity is on the way home
#define STATUS_GOHOME				8

// entity is fleeing
#define	STATUS_FLEEING				9

// entity is working on something
#define	STATUS_WORKING				10

// set after call setWork function
#define STATUS_NEWJOB				11

// work is done
#define STATUS_DONE					12

#define STATUS_BACKHOME				13
//--------------------------------------------------

#define PI 3.14159265

const float MAX_AGE = 100.0f;

// shader types
// for first pass during creating shadow map
#define SHADER_SHADOW	0
// second pass draw object with it's own shader program
#define SHADER_NORMAL	1
#define SHADER_REFLECTION	2
#define SHADER_VIRTUAL	3

#include "../ShaderPool.h"
#include <string.h>

#ifdef _WIN32 
#include <windows.h> 
#endif

#include "../scene/World.h"
#include "../models/ModelPool.h"
#include "../mechanics/PathFinder.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <math.h>
#include <vector>
#include "../console/globalConsole.h"
#include "../dataTypes/Cube.h"
#include "../gadgets/Form.h"
#include "../gadgets/Button.h"
#include "../gadgets/Label.h"
#include "../scene/Timer.h"
#include "../engine/RTSException.h"

class Entity
{
public:
	Entity(glm::vec3 _Pos, float _r, std::string _Name, std::string _modelFName,
			ModelPool *_mPool, PathFinder *_pathfinder);
	virtual ~Entity();

	virtual void draw(int shadertype); // draw model
	virtual void control(float t); // check move vector

	virtual void drawMarker(float size); // draw marker
	virtual void drawBBox(); // draw bounding box

	// move with entity to position
	virtual void goTo(glm::vec2 pos);

	// create unitbar
	virtual void BuildUnitBar(std::string iconFName);

	virtual unsigned int resolveDecision(unsigned int id);

	glm::vec2 get2dPosition();
	glm::vec3 getPosition();

	// detection of collision with point 3D
	bool pointInEntity(glm::vec3 X);

	// detection of collision with cube
	bool CubeInEntity(DataTypes::Cube cube);

	const std::string& getModelFName() const;
	void setModelFName(const std::string& modelFName);
	const std::string& getName() const;
	void setName(const std::string& name);
	const glm::vec3& getPos() const;
	void setPos(const glm::vec3& pos);
	int getType() const;
	void setType(int type);
	int getParentType();
	float getAge() const;
	void setAge(float age);
	bool isMarked() const;
	void setMarked(bool marked);
	bool isInserted() const;
	void setInserted(bool inserted);

	// deturn cube of bouding box
	DataTypes::Cube* getBBox();

	// neighboor detections

	// return absolute highest point of mode bounding box
	// return 0 if there is no bounding box
	float getHightOfBBox();
	float getR() const;
	void setR(float r);
	Gadgets::Form * getUnitBar();
	void setUnitBar(Gadgets::Form * unitButton);

	int getCost();
	int getCostGold();
	void setCost(int c);

	void setSleeping(bool sleeping);

	int getStatus();
	void setStatus(int status);

	// return status value as string
	std::string getStringStatus();
protected:

	// id of entity status
	int status;

	Timer timer;

	// TODO change type and paretType to const
	int type, parentType; // type of entity

	glm::vec3 Pos; // position of entity
	float r; // angle
	std::string Name; // name of entity
	ModelPool *mPool; // reference model pool with model of entity
	std::string modelFName; // model name in model pool
	PathFinder *pathfinder;
	std::vector<GLuint> modelID; // ID of model
	GLuint markModelID; // ID of marker model
	GLuint shaderID; // ID of normal shader
	GLuint shadowShaderID; // ID of shadow shader
	GLuint markerShaderID;
	GLuint virtualShaderID;

	float age; // age of entity
	bool Marked; // true when unit is marked
	float markR; // rotation of marker

	float animationPos;

	// true when entity was inserted to map octree structure
	bool inserted;

	// when True entity is sleeping, not visible, not mooving
	// default false
	bool sleeping;

	//cost of entity
	int cost, costGold;

	bool underConstruction;

	Gadgets::Form *unitBar, *icon;
	Gadgets::Label *infoLabel, *nameLabel;
};
